package com.youlu.campus.web.order.service;

import com.alibaba.fastjson.JSON;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.base.order.enums.OrderPayStatusEnum;
import com.youlu.campus.base.order.enums.OrderStatusEnum;
import com.youlu.campus.base.order.vo.OrderRequest;
import com.youlu.campus.base.order.vo.OrderVO;

import com.youlu.campus.component.SmsUtil;
import com.youlu.campus.entity.ActivityFeedInfo;
import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.ActivityUserRecord;
import com.youlu.campus.entity.CaGroupInfo;
import com.youlu.campus.entity.CaInfo;
import com.youlu.campus.entity.OOrderInfo;
import com.youlu.campus.entity.OrderInfo;
import com.youlu.campus.entity.QQMiniUserPO;
import com.youlu.campus.entity.SmsTemplate;
import com.youlu.campus.entity.UniversityInfo;
import com.youlu.campus.entity.UserActivityReward;
import com.youlu.campus.entity.UserCaInfo;
import com.youlu.campus.entity.UserInviteRecord;
import com.youlu.campus.entity.UserMemberShipInfo;
import com.youlu.campus.entity.UserPO;
import com.youlu.campus.entity.UserRecieveCaRecord;
import com.youlu.campus.entity.VO.PlaceOrderReq;
import com.youlu.campus.entity.VO.req.CaCollectReq;
import com.youlu.campus.entity.VO.req.OrderPayCompensationVO;
import com.youlu.campus.entity.VO.req.OrderRefundOptVO;
import com.youlu.campus.entity.VO.req.ProducerOrderGmvReq;
import com.youlu.campus.entity.VO.res.ActivityRecommendOrderResponse;
import com.youlu.campus.entity.VO.res.CaCollectRes;
import com.youlu.campus.entity.WechatH5UserPO;
import com.youlu.campus.entity.WechatMerchantConfig;
import com.youlu.campus.entity.WechatMiniUserPO;
import com.youlu.campus.entity.commission.DistributorApply;
import com.youlu.campus.entity.commission.dto.DistributorChannelSharingCommissionOrderDTO;
import com.youlu.campus.entity.commission.dto.SharingCommissionOrderDTO;
import com.youlu.campus.entity.course.dto.GoodsOrderDTO;
import com.youlu.campus.entity.domain.ModifyAddressDomain;
import com.youlu.campus.entity.domain.RefundDomain;
import com.youlu.campus.entity.enums.SharingProfitOrderTypeEnum;
import com.youlu.campus.service.activity.ActivityService;
import com.youlu.campus.service.base.BaseService;
import com.youlu.campus.service.base.LockService;
import com.youlu.campus.service.ca.UserRecieveCaRecordService;
import com.youlu.campus.service.ca.impl.CaCollectService;
import com.youlu.campus.service.cache.CacheCaGroupInfoService;
import com.youlu.campus.service.cache.CacheCaInfoService;
import com.youlu.campus.service.card.TsCardService;
import com.youlu.campus.service.commission.DistributorChannelSharingCommissionService;
import com.youlu.campus.service.commission.PaperCaCommissionServiceService;
import com.youlu.campus.service.course.WechatPayService;
import com.youlu.campus.service.data.OrderStatisticsService;
import com.youlu.campus.service.feed.ActivityFeedInfoService;
import com.youlu.campus.service.item.ItemInfoService;
import com.youlu.campus.service.item.ItemStockService;
import com.youlu.campus.service.order.MerchantSharingProfitService;
import com.youlu.campus.service.order.ProducerOrderGmvService;
import com.youlu.campus.service.sms.SmsTemplateService;
import com.youlu.campus.service.university.UniversityInfoService;
import com.youlu.campus.service.visitor.VisitorUserService;
import com.youlu.campus.service.wechatpay.WechatPayCacheService;
import com.youlu.campus.web.ca.service.impl.UserCaInfoServiceImpl;
import com.youlu.campus.web.cms.entity.BannerConfig;
import com.youlu.campus.web.common.ContextUtils;
import com.youlu.campus.web.common.base.RequestContext;
import com.youlu.campus.web.common.utils.CommonUtils;
import com.youlu.campus.web.common.utils.DateTimeUtils;
import com.youlu.campus.web.order.entity.OrderPO;
import com.youlu.campus.web.order.service.pay.PayNotify;
import com.youlu.campus.web.order.service.pay.PlaceOrderServiceEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author zhuhuaiqi
 * @date 2020/8/3 18:51
 */

@Service("orderService-2")
@Slf4j
public class OrderService extends BaseService {

    @Autowired
    private LockService lockService;

    @Autowired
    private HttpServletRequest httpRequest;

    @Autowired
    private WechatPayCacheService wechatPayCacheService;
    @Autowired
    private UserRecieveCaRecordService userRecieveCaRecordService;
    @Autowired
    private OrderStatisticsService orderStatisticsService;

    final public static String payCache = "luyou.pay-cache";

    @Lazy
    @Autowired
    private CacheCaInfoService cacheCaInfoService;

    @Autowired
    private CaCollectService caCollectService;
    @Autowired
    private ActivityService activityService;
    @Autowired
    private com.youlu.campus.service.order.OrderService oService;
    @Autowired
    private SmsUtil smsUtil;
    @Autowired
    private SmsTemplateService smsTemplateService;
    @Autowired
    private VisitorUserService visitorUserService;
    @Autowired
    private ItemStockService itemStockService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Lazy
    @Autowired
    private ActivityFeedInfoService activityFeedInfoService;
    @Autowired
    private ItemInfoService itemInfoService;

    @Autowired
    private MerchantSharingProfitService merchantSharingProfitService;

    @Autowired
    private ProducerOrderGmvService producerOrderGmvService;

    @Autowired
    private WechatPayService wechatPayService;


    @Resource(name = "masterMongoTemplate")
    private MongoTemplate masterMongoTemplate;

    @Autowired
    private TsCardService tsCardService;

    @Autowired
    private PaperCaCommissionServiceService paperCaCommissionServiceService;

    @Autowired
    private DistributorChannelSharingCommissionService distributorChannelSharingCommissionService;
    @Autowired
    private CacheCaGroupInfoService cacheCaGroupInfoService;
    @Lazy
    @Autowired
    private UniversityInfoService universityInfoService;

    @Async
    public void initPaperCaOrderCommission(String activityId) {
        log.info("【纸质证书订单分佣】activityId:{}", activityId);
        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").is(activityId));
        query.addCriteria(Criteria.where("status").nin("0", "6"));
        List<OrderInfo> orderInfoList = this.mongoTemplate.find(query, OrderInfo.class);
        if (CollectionUtils.isEmpty(orderInfoList)) {
            log.warn("【纸质证书订单分佣】activityId:{} end 未找到", activityId);
            return;
        }
        orderInfoList.stream().forEach(paySuccessOrder -> {
            String accountInfoId = paySuccessOrder.getAccountInfoId();
            Integer sharingCommissionOrderAmount = 0;
            //总订单金额减去分拥订单后金额
            UserInviteRecord userInviteRecord = paperCaCommissionServiceService.inviterDistributor(accountInfoId, activityId);
            if (Objects.nonNull(userInviteRecord) && userInviteRecord.getInviterDistributor()) {
                DistributorApply distributorApply = paperCaCommissionServiceService.findByDistributorId(userInviteRecord.getInvitedByUserId());
                if (Objects.nonNull(distributorApply)) {
                    log.info("【纸质证书订单分佣】分销员:{},activityId:{}", distributorApply.getName(), activityId);
                    SharingCommissionOrderDTO sharingCommissionOrderDto = new SharingCommissionOrderDTO();
                    sharingCommissionOrderDto.setActivityId(activityId);
                    sharingCommissionOrderDto.setAppId(paySuccessOrder.getAppId());
                    sharingCommissionOrderDto.setDistributorCommission(distributorApply.getDistributorCommission());
                    sharingCommissionOrderDto.setMerchantId(paySuccessOrder.getMechantId());
                    sharingCommissionOrderDto.setMerchantName(paySuccessOrder.getMechantName());
                    sharingCommissionOrderDto.setPayTime(paySuccessOrder.getPayTime());
                    sharingCommissionOrderDto.setOrderNo(paySuccessOrder.getOrderNo());
                    sharingCommissionOrderDto.setTotalFee(paySuccessOrder.getTotalFee());
                    sharingCommissionOrderDto.setTransactionId(paySuccessOrder.getTransactionId());
                    sharingCommissionOrderDto.setCategory(SharingProfitOrderTypeEnum.PAPER_CA_ORDER.name());
                    sharingCommissionOrderAmount = paperCaCommissionServiceService.doSharingCommissionAmount(sharingCommissionOrderDto);
                    log.info("【纸质证书订单分佣】分销员:{},activityId:{},分销金额:{}", distributorApply.getName(), activityId, sharingCommissionOrderAmount);
                }
            }
        });
        log.info("【纸质证书订单分佣】activityId:{} end", activityId);
    }


    public ActivityRecommendOrderResponse findActivityRecommendByOrderNo(UserPO currentUser, String orderNo) {
        if (StringUtils.isBlank(orderNo)) {
            return null;
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("orderNo").is(orderNo));
        OrderInfo orderInfo = this.mongoTemplate.findOne(query, OrderInfo.class);
        if (Objects.isNull(orderInfo)) {
            log.info("活动推荐 订单号未找到 OrderService.findActivityRecommendByOrderNo order->{}", orderNo);
            return null;
        }
        String activityId = orderInfo.getActivityId();
        query = new Query();
        query.addCriteria(Criteria.where("activityId").is(activityId));
        query.addCriteria(Criteria.where("location").is("order-detail-top"));
        if ("wechat-mini".equals(currentUser.getCurrentPlatform())) {
            query.addCriteria(Criteria.where("appId").is(currentUser.getAppId()));
        }
        query.addCriteria(Criteria.where("platform").is(currentUser.getCurrentPlatform()));
        BannerConfig bannerConfig = this.mongoTemplate.findOne(query, BannerConfig.class);
        if (Objects.isNull(bannerConfig)) {
            log.error("活动推荐 订单号未找到 banner 配置 OrderService.findActivityRecommendByOrderNo orderNo->{},activityId->{}," +
                            "appId->{},platform->{}",
                    orderNo, activityId, currentUser.getAppId(), currentUser.getCurrentPlatform());
            return null;
        }
        ActivityRecommendOrderResponse activityRecommendOrder = new ActivityRecommendOrderResponse();
        activityRecommendOrder.setImageUrl(bannerConfig.getImageUrl());
        activityRecommendOrder.setInnerLinks(bannerConfig.getInnerLinks());
        activityRecommendOrder.setLinkerType(bannerConfig.getLinkerType());
        activityRecommendOrder.setLocation(bannerConfig.getLocation());
        activityRecommendOrder.setTitle(bannerConfig.getTitle());
        activityRecommendOrder.setOuterLinks(bannerConfig.getOuterLinks());
        ActivityInfo activityInfo = this.mongoTemplate.findById(activityId, ActivityInfo.class);
        if (Objects.nonNull(activityInfo)) {
            activityRecommendOrder.setActivityType(activityInfo.getType());
        }
        return activityRecommendOrder;
    }


    /**
     * 下单
     *
     * @return
     */
    public Map<String, String> placeOrder(PlaceOrderReq req) {
        log.info("paperOrder userId {} req {}", RequestContext.getUserId(), req);
        if (StringUtils.isBlank(req.getGoodsCode())) {
            throw new BusinessException("商品编码不能为空~");
        }
        if (super.resubmit(3L, RequestContext.getUserId(), req)) {
            throw new BusinessException("请勿重复发起支付~");
        }
        req.setClientIp(CommonUtils.getRemoteIp(httpRequest));
        OrderBaseService baseService =
                (OrderBaseService) ContextUtils.getBean(PlaceOrderServiceEnum.getClassByGoodsCode(req.getGoodsCode()));
        if (baseService == null) {
            throw new BusinessException("商品编码参数有误~");
        }
        return baseService.placeOrder(req);
    }

    public boolean getOrderPayStatus(String orderNo) {
        boolean result = wechatPayCacheService.getStatus(orderNo);
        log.info(":>>> 查询订单:{} 用户支付:{}", orderNo, result);
        return result;
    }

    /**
     * 处理支付通知
     *
     * @param msg
     * @return
     */
    public boolean orderPayNotify(PayNotify msg) {
        log.info("orderPayNotify msg {}", JSON.toJSONString(msg));
        try {
            Date date = new Date();
            // 处理不同的业务逻辑
//        String keyPrefix = String.format(Constants.ORDER_PAY_PREFIX_KEY, msg.getOrderNo());
//        String biz = redisTemplate.opsForValue().get(keyPrefix);
            String biz = wechatPayCacheService.getBizType(msg.getOrderNo());
            log.info(":>>> 订单:{}, 业务类型为:{}", msg.getOrderNo(), biz);
            if (StringUtils.isNotBlank(biz)) {
                switch (biz) {
                    case "ca":
                        handleCaPayNotify(msg.orderNo, msg.transaction_id, date);
                        break;
                    case "membership":
                        handleMemberShipPayNotify(msg.orderNo, msg.transaction_id, date);
                        break;
                    case "mix":
                        handleMixPayNotify(msg.orderNo, msg.transaction_id, date);
                        break;
                    case "item":
                    case "badge":
                        updateItemOrderInfoStatus(msg.orderNo, msg.transaction_id, date);
                    default:
                        break;
                }
                return true;
            }
            return false;

        } catch (Exception e) {
            log.info(":>>> 处理订单支付通知错误:{}", e);
        }
        return false;
    }

    /**
     * 处理证书购买订单
     *
     * @param orderNo
     * @param transactionId
     * @param date
     */
    @Async
    public void handleCaPayNotify(String orderNo, String transactionId, Date date) {
        log.info(":>>> 开始处理微信支付:{},{},{}", orderNo, transactionId, date);
        String lock = "youlu:order:pay:notify:" + orderNo;
        if (lockService.tryLock(lock, 10L, TimeUnit.SECONDS)) {
            //查询订单
            try {
                Query query = new Query();
                query.addCriteria(Criteria.where("orderNo").is(orderNo));
                UserCaInfo orderPO = mongoTemplate.findOne(query, UserCaInfo.class);
                if (orderPO == null) {
                    log.info(":>>> 订单不存在:{},", orderNo);
                    return;
                }
                if (!orderPO.getCaStatus().equals(0)) {
                    return;
                }
                orderPO.setTransactionId(transactionId);
                orderPO.setCaStatus(1);
                orderPO.setPayTime(date);
                orderPO.setUpdatedTime(date);
                mongoTemplate.save(orderPO);
            } catch (Exception e) {
                log.error("orderPayNotify error orderNo {}", orderNo, e);
            } finally {
                lockService.unLock(lock);
            }
        }
    }

    /**
     * 处理会员购买订单
     *
     * @param orderNo
     * @param transactionId
     * @param date
     */
        private void handleMemberShipPayNotify(String orderNo, String transactionId, Date date) {
        String lock = "youlu:order:pay:notify:" + orderNo;
        if (lockService.tryLock(lock, 10L, TimeUnit.SECONDS)) {
            //查询订单
            try {
                Query query = new Query();
                query.addCriteria(Criteria.where("orderNo").is(orderNo));
                UserMemberShipInfo orderPO = mongoTemplate.findOne(query, UserMemberShipInfo.class);
                if (orderPO == null) {
                    log.error(":>>> 订单编号:{} 的会员购买记录不存在", orderNo);
                    return;
                }
                if (!orderPO.getStatus().equals(0)) {
                    return;
                }
                orderPO.setTransactionId(transactionId);
                // 已经付款
                orderPO.setStatus(1);
                orderPO.setPayTime(date);
                orderPO.setUpdatedTime(date);
                orderPO.setTransactionId(transactionId);
                mongoTemplate.save(orderPO);
                // 更新用户会员权益信息
                Query queryUser = new Query().addCriteria(Criteria.where("id").is(orderPO.getUserId()));
                Update update = new Update();
                update.set("memberShiped", true);
                update.set("remainedNum", 5);
                UpdateResult updateResult = mongoTemplate.updateFirst(queryUser, update, UserPO.class);
                log.info(":>>> 更新用户:{},购买会员结果:{} ", orderPO.getUserId(), updateResult.getModifiedCount() > 0 ? true :
                        false);
            } catch (Exception e) {
                log.error("orderPayNotify error orderNo {}", orderNo, e);
            } finally {
                lockService.unLock(lock);
            }
        }
    }

        private void handleMixPayNotify(String orderNo, String transactionId, Date date) {
        log.info(":>>> 开始处理混合支付通知orderNo:{},交易号:{},日期:{}", orderNo, transactionId, date);
        String lock = String.format("youlu:order:pay:notify:%s", orderNo);
        if (lockService.tryLock(lock, 10L, TimeUnit.SECONDS)) {
            //查询订单
            try {
                Query query = new Query();
                query.addCriteria(Criteria.where("parentOrderNo").is(orderNo));
                UserMemberShipInfo orderPO = mongoTemplate.findOne(query, UserMemberShipInfo.class);
                log.info(":>>> 会员信息订单为:{}", JSON.toJSONString(orderPO));
                if (Objects.nonNull(orderPO) && !orderPO.getStatus().equals(0)) {
                    orderPO.setTransactionId(transactionId);
                    // 已经付款
                    orderPO.setStatus(1);
                    orderPO.setPayTime(date);
                    orderPO.setUpdatedTime(date);
                    orderPO.setTransactionId(transactionId);
                    mongoTemplate.save(orderPO);
                    log.info(":>>> 更新订单:{},会员卡状态为:已付款", orderNo);
                }
                Query queryCa = new Query();
                queryCa.addCriteria(Criteria.where("parentOrderNo").is(orderNo));
                queryCa.addCriteria(Criteria.where("caStatus").is(0));

                Long count = mongoTemplate.count(queryCa, UserCaInfo.class);
                log.info(":>>> 用户证书信息:父订单号:{} 未付款订单为:{}", orderNo, count);
                if (Objects.nonNull(count) && count.intValue() > 0) {
                    Update update = new Update();
                    update.set("transactionId", transactionId);
                    update.set("caStatus", 1);
                    update.set("payTime", date);
                    // 付款完成后变成纸质版
                    update.set("material", 1);
                    update.set("updatedTime", date);
                    UpdateResult updateResult = mongoTemplate.updateMulti(queryCa, update, UserCaInfo.class);
                    log.info(":>>> 更新用户父订单号:{},数量:{} 支付状态为:已经付款", orderNo, updateResult.getModifiedCount());
                    // 发送短信
                    List<UserCaInfo> userCaInfos = mongoTemplate.find(queryCa, UserCaInfo.class);
                    for (UserCaInfo userCaInfo : userCaInfos) {
                        Query query1 =
                                new Query().addCriteria(Criteria.where("activityId").is(userCaInfo.getActivityId()).and("userId").is(userCaInfo.getUserId()));

                    }
                }
                Query queryReward = new Query().addCriteria(Criteria.where("orderNo").is(orderNo));
                Update update = new Update();
                update.set("rewardReceived", Boolean.TRUE);
                update.set("receivedTime", new Date());
                UpdateResult updateResult = mongoTemplate.updateFirst(queryReward, update, UserActivityReward.class);
                this.updateOrderInfoStatus(orderNo, transactionId, date);
                itemStockService.handleItemStock(orderNo);
                orderStatisticsService.incre(orderNo);
                log.info(":>>> 更新订单的领取记录:{},结果:{}", orderNo, updateResult.getModifiedCount() > 0 ? true : false);
                //添加兑换码
                tsCardService.makeRedeemCode(orderNo);
            } catch (Exception e) {
                log.error("orderPayNotify error orderNo {}", orderNo, e);
            } finally {
                lockService.unLock(lock);
            }
        }
    }


    public Page<OrderVO> getUserOrderList(OrderRequest request) {
        log.info("getUserOrderList request {}", request);
        Query query = this.getOrderQuery(request);
        long count = mongoTemplate.count(query, OrderPO.class);
        PageRequest pageRequest = PageRequest.of(request.getPage() - 1, request.getPageSize());
//        query.with(new Sort(Sort.Direction.DESC, "payTime"));
        Sort sort = Sort.by(Sort.Direction.DESC, "payTime");
        query.with(sort);
        List<OrderPO> orderPOS = mongoTemplate.find(query.with(pageRequest), OrderPO.class);
        List<OrderVO> list = orderPOS.stream().map(orderPO -> {
            OrderVO response = new OrderVO();
            BeanUtils.copyProperties(orderPO, response);
            response.setOrderId(orderPO.getId());
            return response;
        }).collect(Collectors.toList());
        return PageableExecutionUtils.getPage(list, pageRequest, () -> count);
    }

    public boolean hasPaperCertificateOrder(String userId, String goodsCode) {
        log.info("hasPaperCertificateOrder userId {}", userId);
        Query query = new Query();
        query.addCriteria(Criteria.where("user.userId").is(userId));
        query.addCriteria(Criteria.where("goods.goodsCode").is(goodsCode));
        query.addCriteria(Criteria.where("payStatus").is(OrderPayStatusEnum.PAID.getCode()));
        query.addCriteria(Criteria.where("status").in(OrderStatusEnum.PAID_OFF.getCode()
                , OrderStatusEnum.SHIPPED.getCode(), OrderStatusEnum.COMPLETE.getCode()));
        query.addCriteria(Criteria.where("deleted").is(false));
        return mongoTemplate.exists(query, OrderPO.class);
    }

    private Query getOrderQuery(OrderRequest request) {
        Query query = new Query();
        if (!CollectionUtils.isEmpty(request.getGoodsCodes())) {
            query.addCriteria(Criteria.where("goods.goodsCode").in(request.getGoodsCodes()));
        }
        if (request.getType() == 1) {
            query.addCriteria(Criteria.where("user.userId").is(RequestContext.getUserId()));
        }
        query.addCriteria(Criteria.where("deleted").is(false));
        query.addCriteria(Criteria.where("payStatus").is(OrderPayStatusEnum.PAID.getCode()));
        query.addCriteria(Criteria.where("status").in(OrderStatusEnum.PAID_OFF.getCode(),
                OrderStatusEnum.REFUND.getCode()
                , OrderStatusEnum.SHIPPED.getCode(), OrderStatusEnum.COMPLETE.getCode()));
        if (StringUtils.isNotBlank(request.getName())) {
            Pattern pattern = Pattern.compile("^.*" + request.getName() + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("user.name").regex(pattern));
        }
        if (StringUtils.isNotBlank(request.getMobile())) {
            Pattern pattern = Pattern.compile("^.*" + request.getMobile() + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("user.mobile").regex(pattern));
        }
        if (request.getStartTime() != null || request.getEndTime() != null) {
            Criteria criteria = Criteria.where("payTime");
            if (request.getStartTime() != null) {
                criteria.gte(request.getStartTime());
            }
            if (request.getEndTime() != null) {
                criteria.lte(request.getEndTime());
            }
            query.addCriteria(criteria);
        }
        return query;
    }

    public void updateOrderInfoStatus(String orderNo, String transactionId, Date date) {
        log.info(":>>> 开始处理订单:{},支付通知:{}", orderNo, transactionId);
        if (StringUtils.isBlank(orderNo) || StringUtils.isBlank(transactionId)) {
            log.info(":>>> 处理订单:{} 通知参数错误", orderNo);
            return;
        }
        Query query = new Query().addCriteria(Criteria.where("orderNo").is(orderNo));
        Update update = new Update();
        /**
         * 状态,0:待付款,1:已付款,2:制作中,3:待发货,4:待收货,5:已收货,6:订单完成,7:订单关闭,8:售后中,9:部分已发货
         */
        update.set("status", "1");
        update.set("updatedTime", date);
        update.set("transactionId", transactionId);
        update.set("payStatus", 1);
        update.set("payTime", date);
        update.set("updatedTime", date);
        update.set("payNotifyTime", date);
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
        findAndModifyOptions.upsert(Boolean.TRUE);
        findAndModifyOptions.returnNew(Boolean.TRUE);
        masterMongoTemplate.updateMulti(query, update, OOrderInfo.class);
        OrderInfo orderModify = masterMongoTemplate.findAndModify(query, update,
                findAndModifyOptions, OrderInfo.class);
        if (Objects.nonNull(orderModify)) {
            String orderNoKey = String.format(UserCaInfoServiceImpl.USER_ORDER_PAY, orderNo);
            String orderJson = this.redisTemplate.opsForValue().get(orderNoKey);
            if (StringUtils.isNotBlank(orderJson)) {
                OrderInfo orderInfo = JSON.parseObject(orderJson, OrderInfo.class);
                orderInfo.setStatus("1");
                this.redisTemplate.delete(orderNoKey);
                this.redisTemplate.opsForValue().set(orderNoKey, JSON.toJSONString(orderInfo), 30L, TimeUnit.MINUTES);
            }
            OrderInfo paySuccessOrder = this.masterMongoTemplate.findOne(query, OrderInfo.class);
            if (Objects.nonNull(paySuccessOrder)) {
                String accountInfoId = paySuccessOrder.getAccountInfoId();
                String activityId = paySuccessOrder.getActivityId();
                Integer sharingCommissionOrderAmount = 0;
                Integer sharingCommissionChannelOrderAmount = 0;
                //总订单金额减去分拥订单后金额
                Integer orderAmountAfter = 0;
                UserInviteRecord userInviteRecord = paperCaCommissionServiceService.inviterDistributor(accountInfoId, activityId);
                if (Objects.nonNull(userInviteRecord) && userInviteRecord.getInviterDistributor()) {
                    DistributorApply distributorApply = paperCaCommissionServiceService.findByDistributorId(userInviteRecord.getInvitedByUserId());
                    if (Objects.nonNull(distributorApply)) {
                        SharingCommissionOrderDTO sharingCommissionOrderDto = new SharingCommissionOrderDTO();
                        sharingCommissionOrderDto.setActivityId(activityId);
                        sharingCommissionOrderDto.setAppId(paySuccessOrder.getAppId());
                        sharingCommissionOrderDto.setDistributorCommission(distributorApply.getDistributorCommission());
                        sharingCommissionOrderDto.setMerchantId(paySuccessOrder.getMechantId());
                        sharingCommissionOrderDto.setMerchantName(paySuccessOrder.getMechantName());
                        sharingCommissionOrderDto.setOrderNo(paySuccessOrder.getOrderNo());
                        sharingCommissionOrderDto.setPayTime(paySuccessOrder.getPayTime());
                        sharingCommissionOrderDto.setTotalFee(paySuccessOrder.getTotalFee());
                        sharingCommissionOrderDto.setTransactionId(transactionId);
                        sharingCommissionOrderDto.setCategory(SharingProfitOrderTypeEnum.PAPER_CA_ORDER.name());
                        sharingCommissionOrderAmount = paperCaCommissionServiceService.doSharingCommissionAmount(sharingCommissionOrderDto);
                    }
                } else {
                    //渠道分拥
                    DistributorChannelSharingCommissionOrderDTO sharingCommissionOrderChannelDto = new DistributorChannelSharingCommissionOrderDTO();
                    sharingCommissionOrderChannelDto.setActivityId(paySuccessOrder.getActivityId());
                    sharingCommissionOrderChannelDto.setAppId(paySuccessOrder.getAppId());
                    sharingCommissionOrderChannelDto.setMerchantId(paySuccessOrder.getMechantId());
                    sharingCommissionOrderChannelDto.setMerchantName(paySuccessOrder.getMechantName());
                    sharingCommissionOrderChannelDto.setOrderNo(orderNo);
                    sharingCommissionOrderChannelDto.setPayTime(paySuccessOrder.getPayTime());
                    sharingCommissionOrderChannelDto.setTotalFee(paySuccessOrder.getTotalFee());
                    sharingCommissionOrderChannelDto.setTransactionId(transactionId);
                    sharingCommissionOrderChannelDto.setCategory(SharingProfitOrderTypeEnum.PAPER_CA_ORDER.name());
                    sharingCommissionOrderChannelDto.setUserId(paySuccessOrder.getAccountInfoId());
                    sharingCommissionOrderChannelDto.setMobile(paySuccessOrder.getMobile());
                    sharingCommissionOrderChannelDto.setName(paySuccessOrder.getName());
                    sharingCommissionOrderChannelDto.setUniversityId(paySuccessOrder.getUniversityId());
                    sharingCommissionOrderChannelDto.setUniversityName(paySuccessOrder.getUniversityName());
                    sharingCommissionChannelOrderAmount = distributorChannelSharingCommissionService.doSharingCommissionAmount(sharingCommissionOrderChannelDto);
                }
                if (sharingCommissionOrderAmount > 0 || sharingCommissionChannelOrderAmount > 0) {
                    orderAmountAfter = paySuccessOrder.getTotalFee() - Math.addExact(sharingCommissionOrderAmount, sharingCommissionChannelOrderAmount);
                } else {
                    orderAmountAfter = paySuccessOrder.getTotalFee();
                }
                paySuccessOrder.setPayTime(date);
                paySuccessOrder.setTransactionId(transactionId);
                paySuccessOrder.setCategory(SharingProfitOrderTypeEnum.PAPER_CA_ORDER.name());
                paySuccessOrder.setTotalFee(orderAmountAfter);
                merchantSharingProfitService.doSharingProfit(paySuccessOrder);
            }
            List<OOrderInfo> subOrderList = this.masterMongoTemplate.find(query, OOrderInfo.class);
            if (!CollectionUtils.isEmpty(subOrderList)) {
                subOrderList.stream().forEach(oOrderInfo -> {
                    cacheCaInfoService.putAndGetItemStock(oOrderInfo.getItemInfoId(), 1L);
                });
            }
            try {
                OrderInfo order = this.masterMongoTemplate.findOne(query, OrderInfo.class);
                //H5收款进入统计
                if (Objects.nonNull(order) && "wechat-h5".equals(order.getPlatform())) {
                    ProducerOrderGmvReq producerOrderGmvReq = new ProducerOrderGmvReq();
                    producerOrderGmvReq.setActivityId(order.getActivityId());
                    producerOrderGmvReq.setPayTime(date);
                    producerOrderGmvReq.setOrderNo(orderNo);
                    producerOrderGmvReq.setGmv((long) order.getTotalFee());
                    this.producerOrderGmvService.doHandleProducerOrderGmv(producerOrderGmvReq);
                }
            } catch (Exception e) {
                log.error("统计gmv->{}", orderNo, e);
            }
        }
        log.info(":>>> 更新订单状态:{},子订单:{},主订单:{}", orderNo);
        this.asyncHandleUserCertificate(orderNo);
        this.createFeed(orderNo);
        this.createCaRecieveRecord(orderNo);

    }

    /**
     * @param orderNo
     */
//    @Async
    public void asyncHandleUserCertificate(String orderNo) {
        try {
            log.info("【已支付纸质版证书-证书编号】处理用户证书编号订单号->{}", orderNo);
            Query query = new Query().addCriteria(Criteria.where("orderNo").is(orderNo));
            OrderInfo orderInfo = this.masterMongoTemplate.findOne(query, OrderInfo.class);
            if (Objects.isNull(orderInfo)) {
                log.error("【已支付纸质版证书-证书编号】订单号->{} 不存在", orderNo);
                return;
            }
            query = new Query();
            query.addCriteria(Criteria.where("openId").is(orderInfo.getOpenId()));
            UserPO currentUser = new UserPO();
            if ("wechat-mini".equals(orderInfo.getPlatform())) {
                WechatMiniUserPO user = mongoTemplate.findOne(query, WechatMiniUserPO.class);
                if (Objects.isNull(user)) {
                    log.error("订单号 ->{} 信息中openid 不存在", orderInfo.getOpenId());
                    return;
                }
                BeanUtils.copyProperties(user, currentUser);
                currentUser.setId(user.getAccountInfoId());
                currentUser.setOpenId(user.getOpenId());
                currentUser.setCurrentPlatform("wechat-mini");
            } else {
                WechatH5UserPO user = mongoTemplate.findOne(query, WechatH5UserPO.class);
                if (Objects.isNull(user)) {
                    log.error("订单号 ->{} 信息中openid 不存在", orderInfo.getOpenId());
                    return;
                }
                BeanUtils.copyProperties(user, currentUser);
                currentUser.setId(user.getAccountInfoId());
                currentUser.setOpenId(user.getOpenId());
            }
            query.addCriteria(Criteria.where("orderNo").is(orderNo));
            query.addCriteria(Criteria.where("certificateNo").exists(Boolean.FALSE));
            query.addCriteria(Criteria.where("caItemType").ne(2));
            List<OOrderInfo> subs = this.masterMongoTemplate.find(query, OOrderInfo.class);
            if (CollectionUtils.isEmpty(subs)) {
                log.error("【已支付纸质版证书-证书编号】订单号->{} 子订单证书编号不需要同步", orderNo);
                return;
            }
            for (OOrderInfo subOrderInfo : subs) {
                String itemInfoId = subOrderInfo.getItemInfoId();
                CaInfo caInfo = cacheCaInfoService.findById(itemInfoId);
                if (Objects.isNull(caInfo)) {
                    log.error("【已支付纸质版证书-证书编号】订单号->{} 证书信息不存在->{}", orderNo, itemInfoId);
                    return;
                }
                if (StringUtils.isBlank(caInfo.getLevel())) {
                    log.error(":>>> 证书:{} 等级为空", caInfo.getId());
                    Query queryCa = new Query();
                    queryCa.addCriteria(Criteria.where("id").is(itemInfoId));
                    caInfo = masterMongoTemplate.findOne(queryCa, CaInfo.class);
                }
                if (Objects.isNull(caInfo)) {
                    log.error("【已支付纸质版证书-证书编号】订单号->{} 证书信息不存在->{}", orderNo, itemInfoId);
                    return;
                }
                if (2 == caInfo.getItemType()) {
                    log.error(":>>> 子订单商品为礼品，不生成证书编号继续:...:{}", subOrderInfo.getId());
                    continue;
                }
                if (2 != caInfo.getItemType() && StringUtils.isNotBlank(subOrderInfo.getCertificateNo())) {
                    log.info(":>>> 子订单:{} 证书编码已经存在，继续处理!!!!");
                    continue;
                }
                String activityId = orderInfo.getActivityId();
                String taskBizType = null;
                if ("v1".equals(orderInfo.getVersion())) {
                    taskBizType = orderInfo.getTaskBizType();
                } else {
                    taskBizType = subOrderInfo.getTaskBizType();
                    if (!StringUtils.isNotBlank(taskBizType)) {
                        CaGroupInfo caGroupInfo = cacheCaGroupInfoService.findById(caInfo.getCaGroupInfoId());
                        if (Objects.nonNull(caGroupInfo)) {
                            taskBizType = caGroupInfo.getTaskBizType();
                        }
                    }
                }

                String level = caInfo.getLevel();
                log.info("【已支付纸质版证书-证书编号】订单号->{} 开始预生成证书编号 活动->{} 证书类型->{} 证书等级 ->{}", orderNo, activityId, taskBizType,
                        level);
                CaCollectReq caCollectReq = new CaCollectReq();
                caCollectReq.setActivityId(orderInfo.getActivityId());
                caCollectReq.setTaskBizType(taskBizType);
                caCollectReq.setCaLevel(caInfo.getLevel());
                caCollectReq.setNowCaBuild(Boolean.TRUE);
                caCollectReq.setCaType("2");
                caCollectReq.setCurrentUser(currentUser);
                caCollectReq.setCaGroupId(caInfo.getCaGroupInfoId());
                caCollectReq.setEdition(caInfo.getEdition());
                caCollectReq.setAppId(orderInfo.getAppId());
                caCollectReq.setPlatform(orderInfo.getPlatform());
                caCollectReq.setName(orderInfo.getCaPrintName());
                caCollectReq.setUniversityId(orderInfo.getUniversityId());
                caCollectReq.setUniversityName(orderInfo.getUniversityName());
                caCollectReq.setMobile(orderInfo.getSignUpMobile());
                caCollectReq.setVersion(orderInfo.getVersion());
                caCollectReq.setSubOrderNo(subOrderInfo.getId());
                CaCollectRes caCertificateNo = caCollectService.collect(caCollectReq);
                log.info("【已支付纸质版证书-证书编号】订单号->{} 开始预生成证书编号 活动->{} 证书类型->{} 证书等级 ->{} 证书编号", orderNo, activityId,
                        taskBizType, level, caCertificateNo.getCertificateNo());
                if (StringUtils.isNotBlank(caCertificateNo.getCertificateNo())) {
                    if ("v1".equals(orderInfo.getVersion())) {
                        Query query1 = new Query();
                        query1.addCriteria(Criteria.where("orderNo").is(orderNo));
                        Update update = new Update();
                        update.set("certificateNo", caCertificateNo.getCertificateNo());
                        update.set("updatedTime", new Date());
                        this.mongoTemplate.updateMulti(query1, update, OOrderInfo.class);
                    } else {
                        if (StringUtils.isNotBlank(subOrderInfo.getTaskBizType()) && StringUtils.isNotBlank(subOrderInfo.getLevel())) {
                            Query query1 = new Query();
                            query1.addCriteria(Criteria.where("orderNo").is(orderInfo.getOrderNo()));
                            query1.addCriteria(Criteria.where("taskBizType").is(taskBizType));
                            query1.addCriteria(Criteria.where("caLevel").is(level));
                            query1.addCriteria(Criteria.where("certificateNo").is(null));
                            Update update = new Update();
                            update.set("certificateNo", caCertificateNo.getCertificateNo());
                            update.set("updatedTime", new Date());
                            UpdateResult result = this.masterMongoTemplate.updateMulti(query1, update, OOrderInfo.class);
                            log.info(":>>> 子订单等级和类型不为空：更新订单:{},子订单证书编号:{},taskBizType:{},caLevel:{},个数:{}",
                                    orderNo, caCertificateNo.getCertificateNo(), taskBizType, caInfo.getLevel(), result.getMatchedCount());
                        } else {
                            Query query2 = new Query();
                            query2.addCriteria(Criteria.where("id").is(subOrderInfo.getId()));
                            query2.addCriteria(Criteria.where("certificateNo").is(null));
                            Update update = new Update();
                            update.set("certificateNo", caCertificateNo.getCertificateNo());
                            update.set("updatedTime", new Date());
                            UpdateResult result2 = this.masterMongoTemplate.updateFirst(query2, update, OOrderInfo.class);
                            log.info(":>>> 子订单等级和类型为空!!!：:{},子订单证书编号:{},taskBizType:{},caLevel:{},个数:{}",
                                    orderNo, caCertificateNo.getCertificateNo(), taskBizType, caInfo.getLevel(), result2.getMatchedCount());
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("【已支付纸质版证书-证书编号】订单号->{} 错误:{}", orderNo, e);
        }

    }

        private void createFeed(String orderNo) {
        log.info(":>>> 开始创建Feed流:{}", orderNo);
        try {

            Query query = new Query().addCriteria(Criteria.where("orderNo").is(orderNo));
            OrderInfo orderInfo = mongoTemplate.findOne(query, OrderInfo.class);
            if (Objects.isNull(orderInfo)) {
                log.error(":>>> 订单信息为空:{}", orderInfo);
                return;
            }
            Query query1 =
                    new Query().addCriteria(Criteria.where("openId").is(orderInfo.getOpenId()).and("appId").is(orderInfo.getAppId()));
            WechatH5UserPO userPO = mongoTemplate.findOne(query1, WechatH5UserPO.class);
            if (Objects.isNull(userPO)) {
                log.error(":>>> appId:{},openId:{} 用户不存在", orderInfo.getOpenId(), orderInfo.getAppId());
                return;
            }
            ActivityFeedInfo info = new ActivityFeedInfo();
            info.setActivityId(orderInfo.getActivityId());
            info.setId(null);
            info.setImageUr(userPO.getAvatarUrl());
            info.setStatus(true);
            info.setDeleted(false);
            info.setCreatedTime(new Date());
            info.setContent(userPO.getNickName() + "领取了证书:" + orderInfo.getTitle());
            info.setActivityStatus(3);
            info.setTtlDate(new Date(new Date().getTime() - 3600000L));
            info = mongoTemplate.insert(info);
            activityFeedInfoService.addActivityFeedInfo(info.getActivityId(), info.getActivityStatus(), info);

        } catch (Exception e) {
            log.error(":>>> 创建Feed流错误:{}", e);
            return;
        }
    }

        private void createCaRecieveRecord(String orderNo) {
        log.info(":>>> 开始创建用户领取证书记录:{}", orderNo);
        Query query = new Query().addCriteria(Criteria.where("orderNo").is(orderNo));
        OrderInfo orderInfo = mongoTemplate.findOne(query, OrderInfo.class);
        if (Objects.isNull(orderInfo)) {
            log.error(":>>> 订单信息为空:{}", orderInfo);
            return;
        }
        OOrderInfo oOrderInfo = mongoTemplate.findOne(query, OOrderInfo.class);
        if (Objects.nonNull(oOrderInfo) && StringUtils.isNotBlank(oOrderInfo.getItemInfoId())) {
            Query queryCa = new Query().addCriteria(Criteria.where("id").is(oOrderInfo.getItemInfoId()));
            CaInfo caInfo = mongoTemplate.findOne(queryCa, CaInfo.class);
            if (Objects.isNull(caInfo)) {
                log.error(":>>> 证书:{} 不存在", oOrderInfo.getItemInfoId());
                return;
            }
            UserRecieveCaRecord recieveCaRecord = new UserRecieveCaRecord();
            recieveCaRecord.setUserId(orderInfo.getAccountInfoId());
            recieveCaRecord.setActivityId(orderInfo.getActivityId());
            recieveCaRecord.setLevel(caInfo.getLevel());
            userRecieveCaRecordService.create(recieveCaRecord);
            log.info(":>>> 新增用户:{} 活动:{},等级:{} 领取记录", orderInfo.getAccountInfoId(), orderInfo.getActivityId(),
                    caInfo.getLevel());

        }
    }



    public void handleOrderTips(String startTime, String endTime) {
        log.info("【更新订单提示语】 start startTime->{} | endTime->{}", startTime, endTime);
        Date startDate = null;
        Date endDate = null;
        Query query = new Query();
        if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
            startDate = DateTimeUtils.StringToDate(startTime);
            endDate = DateTimeUtils.StringToDate(endTime);
            query.addCriteria(Criteria.where("payTime").gte(startDate).lte(endDate));
        }
        query.addCriteria(Criteria.where("status").in("2", "3", "4"));
        List<OrderInfo> orderInfoList = this.mongoTemplate.find(query, OrderInfo.class);
        if (CollectionUtils.isEmpty(orderInfoList)) {
            return;
        }
        log.info("【更新订单提示语】 size ->{} startTime->{} | endTime->{}", orderInfoList.size(), startTime, endTime);
        Date now = new Date();
        final String tips = "同学你好，经物流公司审核您所在区域属于疫情管控区域，暂时不能进行收寄，待可以发出时快递小哥会尝试第一时间发出呢，还请理解并保持期待哦，至此感谢同学们参与活动，由衷祝愿同学们学有所得，未来可期！有问题可电话联系物流负责老师：李老师 18518002032  （工作时间：早10:00--晚18:00）。";
        for (OrderInfo orderInfo : orderInfoList) {
            Query querySubOrder = new Query();
            querySubOrder.addCriteria(Criteria.where("orderNo").is(orderInfo.getOrderNo()));
            querySubOrder.addCriteria(Criteria.where("status").is("2"));
            List<OOrderInfo> subOrderList = this.mongoTemplate.find(querySubOrder, OOrderInfo.class);
            if (!CollectionUtils.isEmpty(subOrderList)) {
                log.info("【更新订单提示语】 子订单size ->{} startTime->{} | endTime->{}", subOrderList.size(), startTime,
                        endTime);
                for (OOrderInfo oOrderInfo : subOrderList) {
                    CaInfo caInfo = oOrderInfo.getCaInfo();
                    if (Objects.isNull(caInfo)) {
                        caInfo = this.mongoTemplate.findById(oOrderInfo.getItemInfoId(), CaInfo.class);
                    }
                    log.info("【更新订单提示语】 子订单 ->{} startTime->{} | endTime->{}", oOrderInfo.getOOrderNo(), startTime,
                            endTime);
                    String inStockTips = caInfo.getInStockTips();
                    if (StringUtils.isBlank(inStockTips)) {
                        caInfo = this.mongoTemplate.findById(oOrderInfo.getItemInfoId(), CaInfo.class);
                        if (Objects.nonNull(caInfo)) {
                            inStockTips = caInfo.getInStockTips();
                        }
                    }
                    Query querySubOrder2 = new Query();
                    querySubOrder2.addCriteria(Criteria.where("id").is(oOrderInfo.getId()));
                    Update update = new Update();
                    update.set("tips", inStockTips);
                    update.set("updatedTime", now);
                    this.mongoTemplate.updateFirst(querySubOrder2, update, OOrderInfo.class);

                }
            }

        }
        log.info("【更新订单提示语】 end startTime->{} | endTime->{}", startTime, endTime);
    }


    public void handleOrderCertificate(String activityId, String startTime, String endTime) {
        Date startDate = null;
        Date endDate = null;
        Query query = new Query();
        if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
            startDate = DateTimeUtils.StringToDate(startTime);
            endDate = DateTimeUtils.StringToDate(endTime);
            query.addCriteria(Criteria.where("payTime").gte(startDate).lte(endDate));
        }
        log.info("开始处理时间->{}", startTime);
        query.addCriteria(Criteria.where("activityId").is(activityId));
        query.addCriteria(Criteria.where("status").in("1", "2"));
        log.info("查询条件->{}开始处理时间->{}", query, startTime);
        List<OrderInfo> listOrderList = this.mongoTemplate.find(query, OrderInfo.class);
        if (CollectionUtils.isEmpty(listOrderList)) {
            return;
        }
        for (OrderInfo orderInfo : listOrderList) {
            try {
                this.asyncHandleUserCertificate(orderInfo.getOrderNo());
            } catch (Exception e) {
                log.error("错误->{}", e);
                continue;
            }
        }
        log.info("已完成处理时间->{}", startTime);
    }

    //更新节能活动订单未有详细地址和收货人和收货手机号相同的
    public void orderAddressUpdate() {
        String startTime = "2021-09-19 12:14:00";
        String endTime = "2021-09-19 17:10:00";
        Query query = new Query();
        Date startDate = DateTimeUtils.StringToDate(startTime);
        Date endDate = DateTimeUtils.StringToDate(endTime);
        query.addCriteria(Criteria.where("payTime").gte(startDate));
        query.addCriteria(Criteria.where("activityId").is("6119dfde60d5e87e7e3b0b19"));
        query.addCriteria(Criteria.where("status").is("1"));
        query.addCriteria(Criteria.where("address").exists(Boolean.FALSE));
        List<OrderInfo> list = this.mongoTemplate.find(query, OrderInfo.class);
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(list)) {
            return;
        }
        list.stream().forEach(orderInfo -> {
            doOrderOrderInfo(orderInfo);
        });
    }

    private void doOrderOrderInfo(OrderInfo orderInfo) {
        if (!orderInfo.getMobile().equals(orderInfo.getName())) {
            return;
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("openId").is(orderInfo.getOpenId()));
        query.addCriteria(Criteria.where("activityId").is("6119dfde60d5e87e7e3b0b19"));
        query.addCriteria(Criteria.where("taskBizType").is(orderInfo.getTaskBizType()));
        query.addCriteria(Criteria.where("address").exists(Boolean.TRUE));
        query.with(Sort.by(Sort.Direction.DESC, "createdTime"));
        ActivityUserRecord user = this.mongoTemplate.findOne(query, ActivityUserRecord.class);
        if (Objects.isNull(user)) {
            log.error("订单号->{} 用户 - >{} 查询错误", orderInfo.getOrderNo(), orderInfo.getOpenId());
            return;
        }
        query = new Query();
        query.addCriteria(Criteria.where("id").is(orderInfo.getId()));
        Update update = new Update();
        update.set("address", user.getAddress());
        update.set("name", user.getRecieveName());
        update.set("dataMark", Boolean.TRUE);
        this.mongoTemplate.updateFirst(query, update, OrderInfo.class);
    }

    /**
     * 获取修改地址详情
     *
     * @param id
     * @return
     */
    public ModifyAddressDomain getModifyAddressDetail(String id) {
        OrderInfo orderInfo = this.findOne(id);
        if (Objects.isNull(orderInfo)) {
            log.error(":>>> 订单:{} 不存在", id);
            throw new BusinessException("订单不存在");
        }
        ActivityInfo activityInfo = activityService.findOne(orderInfo.getActivityId());
        if (Objects.isNull(activityInfo)) {
            log.error(":>>> 活动不存在:{} 不存在", orderInfo.getActivityId());
            throw new BusinessException("活动不存在");
        }
        ModifyAddressDomain modifyAddressDomain = new ModifyAddressDomain();
        modifyAddressDomain.setId(orderInfo.getId());
        modifyAddressDomain.setShowCaInfo(orderInfo.isShowCaInfo());
        modifyAddressDomain.setModifyAddressDesc(activityInfo.getModifyAddressDesc());
        if (Boolean.TRUE.equals(activityInfo.getCanModifyAddress())) {
            if ("1".equals(orderInfo.getStatus()) && (new Date().getTime() - orderInfo.getPayTime().getTime()) <= 12 * 60 * 3600 * 1000L) {
                BeanUtils.copyProperties(orderInfo, modifyAddressDomain);
                modifyAddressDomain.setModifyAddressDesc(activityInfo.getModifyAddressDesc());
                modifyAddressDomain.setCanModifyAddress(true);
            } else {
                modifyAddressDomain.setCanModifyAddress(false);
                modifyAddressDomain.setNotModifyAddressDesc(activityInfo.getNotModifyAddressDesc());
            }
        } else {
            modifyAddressDomain.setCanModifyAddress(false);
            modifyAddressDomain.setNotModifyAddressDesc(activityInfo.getNotModifyAddressDesc());
        }
        log.info(":>>> 活动:{} ,订单:{} 地址修改详情:{},不能修改地址图片:{}", activityInfo.getId(), id,
                JSON.toJSON(modifyAddressDomain), activityInfo.getNotModifyAddressDesc());
        return modifyAddressDomain;
    }

    public boolean modifyAddressDetail(ModifyAddressDomain req) {
        OrderInfo orderInfo = this.findOne(req.getId());
        if (Objects.isNull(orderInfo)) {
            log.error(":>>> 订单:{} 不存在", req.getId());
            throw new BusinessException("订单不存在");
        }
        ActivityInfo activityInfo = activityService.findOne(orderInfo.getActivityId());
        if (Objects.isNull(activityInfo)) {
            log.error(":>>> 活动不存在:{} 不存在", orderInfo.getActivityId());
            throw new BusinessException("活动不存在");
        }
        if (Boolean.FALSE.equals(activityInfo.getCanModifyAddress()) || !"1".equals(orderInfo.getStatus())) {
            log.error(":>>> 地址不允许修改");
            throw new BusinessException("地址不允许修改");
        }
        if ((new Date().getTime() - orderInfo.getPayTime().getTime()) > 12 * 60 * 3600 * 1000L) {
            log.error(":>>> 地址不允许修改");
            throw new BusinessException("地址不允许修改");
        }
        Query query = new Query().addCriteria(Criteria.where("id").is(req.getId()));
        Update update = new Update();
        if (StringUtils.isNotBlank(req.getName())) {
            update.set("name", req.getName());
        }
        if (StringUtils.isNotBlank(req.getMobile())) {
            update.set("mobile", req.getMobile());
        }
        if (StringUtils.isNotBlank(req.getProvince())) {
            update.set("province", req.getProvince());
        }
        if (StringUtils.isNotBlank(req.getCity())) {
            update.set("city", req.getCity());
        }
        if (StringUtils.isNotBlank(req.getArea())) {
            update.set("area", req.getArea());
        }
        if (StringUtils.isNotBlank(req.getAddress())) {
            update.set("address", req.getAddress());
        }
        if (StringUtils.isNotBlank(req.getCaPrintName())) {
            update.set("caPrintName", req.getCaPrintName());
        }
        if (StringUtils.isNotBlank(req.getUniversityId())) {
            update.set("universityId", req.getUniversityId());
            UniversityInfo universityInfo = universityInfoService.findOne(req.getUniversityId());
            if (Objects.nonNull(universityInfo)) {
                update.set("universityName", universityInfo.getName());
            }
        }
        update.set("updatedTime", new Date());
        return mongoTemplate.updateFirst(query, update, OrderInfo.class).getModifiedCount() > 0 ? true : false;
    }

    public OrderInfo findOne(String id) {
        Query query = new Query().addCriteria(Criteria.where("id").is(id));
        OrderInfo orderInfo = mongoTemplate.findOne(query, OrderInfo.class);
        Query querySubOrder = new Query().addCriteria(Criteria.where("orderNo").is(orderInfo.getOrderNo()));
        List<OOrderInfo> subOrder = mongoTemplate.find(querySubOrder, OOrderInfo.class);
        boolean hasCa = false;
        for (OOrderInfo oOrderInfo : subOrder) {
            if (Objects.isNull(oOrderInfo.getPayPrice())) {
                oOrderInfo.setPayPrice(oOrderInfo.getItemPrice());
            }
            if (StringUtils.isNotBlank(oOrderInfo.getItemInfoId())) {
                Query query1 = new Query().addCriteria(Criteria.where("id").is(oOrderInfo.getItemInfoId()));
                CaInfo caInfo = mongoTemplate.findOne(query1, CaInfo.class);
                /**
                 * 1、证书
                 * 2、礼品
                 * 3、证书+礼品
                 */
                if (Objects.nonNull(caInfo)) {
                    oOrderInfo.setLevel(caInfo.getLevel());
                    oOrderInfo.setEdition(caInfo.getEdition());
                    orderInfo.setLevel(caInfo.getLevel());
                    orderInfo.setEdition(caInfo.getEdition());
                    if (!hasCa && 2 != caInfo.getItemType()) {
                        hasCa = true;
                    }
                }
            }
        }
        orderInfo.setOOrderInfos(subOrder);
        orderInfo.setShowCaInfo(hasCa);
        return orderInfo;
    }

    /**
     * 获取退款详情
     *
     * @param id
     * @return
     */
    public RefundDomain getRefundDetail(String id, String userId) {
        log.info(":>>> 开始获取订单退款详情id:{},userId:{}", id, userId);
        OrderInfo orderInfo = this.findOne(id);
        if (Objects.isNull(orderInfo)) {
            log.error(":>>> 订单:{} 不存在", id);
            throw new BusinessException("订单不存在");
        }
        List<String> uids = visitorUserService.findCorrentUserId(userId);
        log.info(":>>> 用户:{} 相关联的uids:{}", userId, JSON.toJSON(uids));
        RefundDomain modifyAddressDomain = new RefundDomain();
        if (!uids.contains(orderInfo.getAccountInfoId())) {
            log.error(":>>> 您没有购买该订单", orderInfo.getOrderNo());
            throw new BusinessException("当前订单不是您的订单，请联系客服确认");
        }
        if ("1".equals(orderInfo.getRefundStatus()) || "2".equals(orderInfo.getRefundStatus()) || "3".equals(orderInfo.getRefundStatus())) {
            log.error(":>>> 当前订单已经在退款中", orderInfo.getOrderNo());
            throw new BusinessException("您已提交退款申请，将在3个工作日内完成退款");
        }
        ActivityInfo activityInfo = activityService.findOne(orderInfo.getActivityId());
        if (Objects.isNull(activityInfo)) {
            log.error(":>>> 活动不存在:{} 不存在", orderInfo.getActivityId());
            throw new BusinessException("活动不存在");
        }
        modifyAddressDomain.setRefundDesc(activityInfo.getRefundDesc());
        if ("wechat-mini".equals(orderInfo.getPlatform()) || Boolean.TRUE.equals(activityInfo.getCanRefund()) || Boolean.TRUE.equals(orderInfo.getSupportRefund())) {
            if ("1".equals(orderInfo.getStatus()) && (System.currentTimeMillis() - orderInfo.getPayTime().getTime()) <= 12 * 3600 * 1000L) {
                BeanUtils.copyProperties(orderInfo, modifyAddressDomain);
                modifyAddressDomain.setRefundDesc(activityInfo.getRefundDesc());
                modifyAddressDomain.setCanRefund(true);
                modifyAddressDomain.setTotalFee(orderInfo.getTotalFee());
            } else {
                modifyAddressDomain.setCanRefund(false);
                if (StringUtils.isBlank(activityInfo.getNotRefundDesc())) {
                    modifyAddressDomain.setNotRefundDesc("https://qiniu.gqgood.com/reject-refund-20210910.jpeg");
                } else {
                    modifyAddressDomain.setNotRefundDesc(activityInfo.getNotRefundDesc());
                }

            }
        } else {
            modifyAddressDomain.setCanRefund(false);
            if (StringUtils.isBlank(activityInfo.getNotRefundDesc())) {
                modifyAddressDomain.setNotRefundDesc("https://qiniu.gqgood.com/reject-refund-20210910.jpeg");
            } else {
                modifyAddressDomain.setNotRefundDesc(activityInfo.getNotRefundDesc());
            }
        }
        modifyAddressDomain.setOrderInfo(orderInfo);
        log.info(":>>> 活动:{},订单:{} 退款详情详情:{},不能退款信息:{} ", activityInfo.getId(), id, JSON.toJSON(modifyAddressDomain),
                activityInfo.getNotRefundDesc());
        return modifyAddressDomain;
    }

    public boolean refund(RefundDomain req) {
        log.info(":>>> 开始处理退款:{}", JSON.toJSONString(req));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getId()) || Objects.isNull(req.getRefundFee()) ||
                StringUtils.isBlank(req.getRefundComment())) {
            log.error(":>>> 退款请求参数错误:");
            throw new BusinessException("退款请求参数错误");
        }
        OrderInfo orderInfo = this.findOne(req.getId());
        if (Objects.isNull(orderInfo)) {
            log.error(":>>> 订单:{} 不存在", req.getId());
            throw new BusinessException("订单不存在");
        }
        if (!"1".equals(orderInfo.getStatus()) || (System.currentTimeMillis() - orderInfo.getPayTime().getTime()) > 12 * 60 * 3600 * 1000L) {
            log.error(":>>> 订单:{} 不满足退款条件");
            throw new BusinessException("订单不满足退款条件");
        }
        Query query1 = new Query().addCriteria(Criteria.where("orderNo").is(orderInfo.getOrderNo()));
        List<OOrderInfo> subOrderInfos = mongoTemplate.find(query1, OOrderInfo.class);
        if (CollectionUtils.isEmpty(subOrderInfos)) {
            log.error(":>>> 订单:{} 不存在子订单", orderInfo.getOrderNo());
            throw new BusinessException("子订单不存在");
        }
        switch (orderInfo.getBizFrom()) {
            case "self": {
                log.info(":>>> 订单:{} 为自有订单:{}", orderInfo.getOrderNo());
                OrderRefundOptVO preRefundReq = new OrderRefundOptVO();
                HashMap<String, Integer> sub = new HashMap<>();
                for (OOrderInfo subOrderInfo : subOrderInfos) {
                    sub.put(subOrderInfo.getOOrderNo(), subOrderInfo.getSalePrice());
                }
                preRefundReq.setId(req.getId());
                preRefundReq.setRefundFee(req.getRefundFee());
                preRefundReq.setSubOrders(sub);
                preRefundReq.setRefundDesc("用户发起退款");
                preRefundReq.setRefundComment(req.getRefundComment());
                preRefundReq.setAlipayAccount(req.getAlipayAccount());
                preRefundReq.setRefundApplyUserType(req.getRefundApplyUserType());
                preRefundReq.setRefundApplyPlatform(req.getRefundApplyPlatform());
                preRefundReq.setRefundApplyAppId(req.getRefundApplyAppId());
                boolean re = oService.preRefund(preRefundReq);
                log.info(":>>> 订单:{} 预退款结果:{}", orderInfo.getOrderNo(), re);
//                    OrderRefundOptVO r = new OrderRefundOptVO();
//                    r.setId(orderInfo.getId());
//                    r.setVerifyStatus(2);
//                    r.setSubOrders(sub);
//                    r.setRefundDesc("系统自动退款");
//                    oService.doRefund(r);
                return true;
            }
            case "third": {
                log.info(":>>> 订单:{} 为三方订单:{}", orderInfo.getOrderNo());
                OrderRefundOptVO preRefundReq = new OrderRefundOptVO();
                HashMap<String, Integer> sub = new HashMap<>();
                for (OOrderInfo subOrderInfo : subOrderInfos) {
                    sub.put(subOrderInfo.getOOrderNo(), subOrderInfo.getSalePrice());
                }
                preRefundReq.setId(req.getId());
                preRefundReq.setRefundFee(req.getRefundFee());
                preRefundReq.setSubOrders(sub);
                preRefundReq.setRefundDesc("用户发起退款");
                preRefundReq.setRefundComment(req.getRefundComment());
                preRefundReq.setAlipayAccount(req.getAlipayAccount());
                preRefundReq.setRefundApplyUserType(req.getRefundApplyUserType());
                preRefundReq.setRefundApplyPlatform(req.getRefundApplyPlatform());
                preRefundReq.setRefundApplyAppId(req.getRefundApplyAppId());
                boolean re = oService.preRefund(preRefundReq);
                log.info(":>>> 订单:{} 预退款结果:{}", orderInfo.getOrderNo(), re);
                return true;
            }
            default:
                break;
        }
        return false;

    }

    public void updateItemOrderInfoStatus(String orderNo, String transactionId, Date date) {
        log.info(":>>> 开始处理订单:{},支付通知:{}", orderNo, transactionId);
        if (StringUtils.isBlank(orderNo) || StringUtils.isBlank(transactionId)) {
            log.info(":>>> 处理订单:{} 通知参数错误", orderNo);
            return;
        }
        Query query = new Query().addCriteria(Criteria.where("orderNo").is(orderNo));
        Update update = new Update();
        /**
         * 状态,0:待付款,1:已付款,2:制作中,3:待发货,4:待收货,5:已收货,6:订单完成,7:订单关闭,8:售后中,9:部分已发货
         */
        update.set("status", "1");
        update.set("updatedTime", date);
        update.set("transactionId", transactionId);
        update.set("payStatus", 1);
        update.set("payTime", date);
        update.set("updatedTime", date);
        update.set("payNotifyTime", date);
        UpdateResult updateResult = mongoTemplate.updateMulti(query, update, OOrderInfo.class);
        UpdateResult updateResultOrder = mongoTemplate.updateFirst(query, update, OrderInfo.class);
        if (updateResultOrder.getModifiedCount() > 0) {
            String orderNoKey = String.format(UserCaInfoServiceImpl.USER_ORDER_PAY, orderNo);
            String orderJson = this.redisTemplate.opsForValue().get(orderNoKey);
            if (StringUtils.isNotBlank(orderJson)) {
                OrderInfo orderInfo = JSON.parseObject(orderJson, OrderInfo.class);
                orderInfo.setStatus("1");
                this.redisTemplate.delete(orderNoKey);
                this.redisTemplate.opsForValue().set(orderNoKey, JSON.toJSONString(orderInfo), 30L, TimeUnit.MINUTES);
            }
        }
        log.info(":>>> 更新订单状态:{},子订单:{},主订单:{}", orderNo, updateResult.getModifiedCount(),
                updateResultOrder.getModifiedCount());
        this.createItemFeed(orderNo);
    }

    /**
     * 发送付款成功短信
     *
     * @param orderNo
     */
    private void sendAfterPaySms(String orderNo) {
        log.info(":>>> 开始发送付款成功短信:{}", orderNo);
        Query query = new Query().addCriteria(Criteria.where("orderNo").is(orderNo));
        OrderInfo orderInfo = mongoTemplate.findOne(query, OrderInfo.class);
        if (Objects.isNull(orderInfo) || StringUtils.isBlank(orderInfo.getMobile())) {
            log.error(":>>> 订单不存在:{}", orderNo);
            return;
        }
        // 发送短信通知
        String[] params = new String[1];
        params[0] = "赞我";
        try {
            SmsTemplate smsTemplate = smsTemplateService.findBySmsTemplate("", "赞我", "after-pay");
            if (Objects.isNull(smsTemplate) || StringUtils.isBlank(smsTemplate.getSign()) || Objects.isNull(smsTemplate.getTempalteId())) {
                log.error(":>>> 短信模版配置错误:没有配置");
                throw new BusinessException("短信模版配置错误");
            }
            smsUtil.sendSmsWithContent("赞我", orderInfo.getMobile(), smsTemplate.getTempalteId(), params);

        } catch (Exception e) {
            log.error(":>>> 发送付款成功短信错误:{}", e);
            return;
        }
    }

    private void createItemFeed(String orderNo) {
        log.info(":>>> 开始创建商品Feed流:{}", orderNo);
        try {

            Query query = new Query().addCriteria(Criteria.where("orderNo").is(orderNo));
            OrderInfo orderInfo = mongoTemplate.findOne(query, OrderInfo.class);
            if (Objects.isNull(orderInfo)) {
                log.error(":>>> 订单信息为空:{}", orderInfo);
                return;
            }
            Query query1 =
                    new Query().addCriteria(Criteria.where("openId").is(orderInfo.getOpenId()).and("appId").is(orderInfo.getAppId()));
            QQMiniUserPO userPO = mongoTemplate.findOne(query1, QQMiniUserPO.class);
            if (Objects.isNull(userPO)) {
                log.error(":>>> appId:{},openId:{} 用户不存在", orderInfo.getOpenId(), orderInfo.getAppId());
                return;
            }
            ActivityFeedInfo info = new ActivityFeedInfo();
            info.setActivityId(orderInfo.getActivityId());
            info.setId(null);
            info.setImageUr(userPO.getAvatarUrl());
            info.setStatus(true);
            info.setDeleted(false);
            info.setCreatedTime(new Date());
            info.setContent(userPO.getNickName() + "购买了:" + orderInfo.getTitle());
            info.setActivityStatus(3);
            info.setTtlDate(new Date(new Date().getTime() - 3600000L));
            info = mongoTemplate.insert(info);
            itemInfoService.addItemFeedInfo("item", info);

        } catch (Exception e) {
            log.error(":>>> 创建Feed流错误:{}", e);
            return;

        }
    }

    public void initStock(String activityId) {
        log.info("【初始化订单商品库存】 start activityId->{}", activityId);

        Integer pageNo = 1;
        Integer pageSize = 1000;
        while (true) {
            PageRequest pageRequest = PageRequest.of(pageNo - 1, pageSize);
            Query query = new Query();
            query.addCriteria(Criteria.where("activityId").is(activityId));
            query.addCriteria(Criteria.where("status").in("1", "2", "4", "5"));
            List<OrderInfo> orderList = this.mongoTemplate.find(query.with(pageRequest), OrderInfo.class);
            if (CollectionUtils.isEmpty(orderList)) {
                log.warn("【初始化订单商品库存】 end activityId->{}", activityId);
                break;
            }
            List<String> orderNoList = orderList.stream().map(OrderInfo::getOrderNo).collect(Collectors.toList());
            query = new Query();
            query.addCriteria(Criteria.where("orderNo").in(orderNoList));
            List<OOrderInfo> subOrderList = this.mongoTemplate.find(query, OOrderInfo.class);
            if (CollectionUtils.isEmpty(subOrderList)) {
                break;
            }
            subOrderList.stream().forEach(subOrder -> {
                cacheCaInfoService.putAndGetItemStock(subOrder.getItemInfoId(), 1L);
            });
            pageNo++;
        }
        log.info("【初始化订单商品库存】 end activityId->{}", activityId);
    }

    public void orderPayCompensation(OrderPayCompensationVO orderPayCompensation) {
        String activityId = orderPayCompensation.getActivityId();
        String startTime = orderPayCompensation.getStartTime();
        String endTime = orderPayCompensation.getEndTime();
        Integer pageNo = orderPayCompensation.getPageNo();
        Integer pageSize = orderPayCompensation.getPageSize();
        if (StringUtils.isBlank(startTime) || StringUtils.isBlank(endTime)) {
            log.error("【订单支付对账】activityId ->{} startTime->{} endTime->{}", activityId, startTime, endTime);
            return;
        }

        log.info("【订单支付对账】activityId ->{} startTime->{} endTime->{}", activityId, startTime, endTime);
        Date startDate = com.youlu.campus.common.utils.DateTimeUtils.StringToDate(startTime);
        Date endDate = com.youlu.campus.common.utils.DateTimeUtils.StringToDate(endTime);
        PageRequest pageRequest = PageRequest.of(pageNo - 1, pageSize);
        Query query = new Query();
        if (ArrayUtils.isNotEmpty(orderPayCompensation.getOrderList())) {
            query.addCriteria(Criteria.where("orderNo").in(orderPayCompensation.getOrderList()));
        }
        query.addCriteria(Criteria.where("activityId").is(activityId));
        query.addCriteria(Criteria.where("createdTime").gte(startDate).lte(endDate));
        query.addCriteria(Criteria.where("status").is("0"));
        List<OrderInfo> orderList = this.mongoTemplate.find(query.with(pageRequest), OrderInfo.class);
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(orderList)) {
            log.warn("【订单支付对账】 未查询到 activityId ->{} startTime->{} endTime->{} pageNo ->{},pageSize->{}", activityId,
                    startTime,
                    endTime, pageNo, pageSize);
            return;
        }
        orderList.parallelStream().forEach(orderInfo -> {
            log.info("【订单支付对账】开始处理订单 orderNo ->{} | activityId ->{} ", orderInfo.getOrderNo(), activityId);
            GoodsOrderDTO dto = new GoodsOrderDTO();
            dto.setOrderNo(orderInfo.getOrderNo());
            dto.setAppId(orderInfo.getAppId());
            SimpleDateFormat formatter2 = new SimpleDateFormat("yyyyMMddHHmmss");
            WechatMerchantConfig config = wechatPayService.getWechatMerchantConfigById(orderInfo.getMechantId());
            Triple<Boolean, Map, String> re = wechatPayService.queryOrder(dto, config);
            if (re.getLeft()) {
                String payStaus = re.getMiddle().get("trade_state").toString();
                log.info("orderNo:{}|支付状态：{}", orderInfo.getOrderNo(), payStaus);
                if ("SUCCESS".equals(payStaus)) {
                    log.info("支付成功");
                    String payTime = re.getMiddle().get("time_end").toString();
                    String transactionId = re.getMiddle().get("transaction_id").toString();
                    if (!StringUtils.isAllBlank(payTime, transactionId)) {
                        log.info("orderNo:{}|支付状态：{},支付时间:{},交易号:{}", orderInfo.getOrderNo(), payStaus, payTime, transactionId);
                        Query query1 = new Query();
                        query1.addCriteria(Criteria.where("id").is(orderInfo.getId()));
                        Update update = new Update();
                        /**
                         * 状态,0:待付款,1:已付款,2:制作中,3:待发货,4:待收货,5:已收货,6:订单完成,7:订单关闭,8:售后中,9:部分已发货
                         */
                        Date date = null;
                        try {
                            date = formatter2.parse(payTime);
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        update.set("status", "1");
                        update.set("transactionId", transactionId);
                        update.set("payStatus", 1);
                        update.set("updatedTime", new Date());
                        update.set("payTime", date);
                        update.set("payNotifyTime", date);
                        Query query2 = new Query();
                        query2.addCriteria(Criteria.where("orderNo").is(orderInfo.getOrderNo()));
                        UpdateResult updateResult = mongoTemplate.updateMulti(query2, update, OOrderInfo.class);
                        UpdateResult updateResultOrder = mongoTemplate.updateFirst(query1, update, OrderInfo.class);
                        if (updateResultOrder.getModifiedCount() > 0) {
                            try {
                                OrderInfo order = this.mongoTemplate.findOne(query2, OrderInfo.class);
                                //H5收款进入统计
                                if (Objects.nonNull(order) && "wechat-h5".equals(order.getPlatform())) {
                                    ProducerOrderGmvReq producerOrderGmvReq = new ProducerOrderGmvReq();
                                    producerOrderGmvReq.setActivityId(order.getActivityId());
                                    producerOrderGmvReq.setPayTime(date);
                                    producerOrderGmvReq.setOrderNo(orderInfo.getOrderNo());
                                    producerOrderGmvReq.setGmv((long) order.getTotalFee());
                                    this.producerOrderGmvService.doHandleProducerOrderGmv(producerOrderGmvReq);
                                }
                            } catch (Exception e) {
                                log.error("统计gmv->{}", orderInfo.getOrderNo(), e);
                            }
                            this.asyncHandleUserCertificate(orderInfo.getOrderNo());
                        }
                    }
                }
            }
        });

    }

    public List<OrderInfo> syncCaNumber(String aid, String batchId, Date start, Date end) {
        log.info(":>>> 开始同步证书编号:{},{},{}", batchId, start, end);
        Date date = new Date();
        Query query = new Query();
        Criteria criteriaPay = new Criteria();
        if (start != null || end != null) {
            criteriaPay = Criteria.where("createdTime");
            if (start != null) {
                criteriaPay.gte(start);
            }
            if (end != null) {
                criteriaPay.lte(end);
            }
        }
        query.addCriteria(criteriaPay);
        query.addCriteria(Criteria.where("status").ne("0"));
        query.addCriteria(Criteria.where("delete").ne(Boolean.TRUE));
        if (StringUtils.isNotBlank(aid)) {
            query.addCriteria(Criteria.where("activityId").is(aid));
        }
        List<OrderInfo> orderInfos = mongoTemplate.find(query, OrderInfo.class);
        for (OrderInfo orderInfo : orderInfos) {
            Query query1 = new Query();
            query1.addCriteria(Criteria.where("id").is(orderInfo.getId()));
            Update update = new Update();
            update.set("caSyncBatchId", batchId);
            update.set("updatedTime", date);
            mongoTemplate.updateFirst(query1, update, OrderInfo.class);
            Query querySub = new Query();
            querySub.addCriteria(Criteria.where("orderNo").is(orderInfo.getOrderNo()));
            mongoTemplate.updateMulti(querySub, update, OOrderInfo.class);
        }
        return orderInfos;
    }

    public OrderInfo findByOrderNo(String orderNo) {
        Query query1 = new Query();
        query1.addCriteria(Criteria.where("orderNo").is(orderNo));
        return mongoTemplate.findOne(query1, OrderInfo.class);
    }


}
